import React, { useEffect, useState } from 'react';
import { ICompany, IFile } from '@/ts/core';
import { useEffectOnce } from 'react-use';
import orgCtrl from '@/ts/controller';
import { Collapse, Empty, message, Spin, Tag } from 'antd';
import EntityIcon from '@/components/Common/GlobalComps/entityIcon';
import ListMode from '@/components/Directory/views/listMode';
import './index.less';
import { IAssignTask } from '@/ts/core/work/assign';
import OrgIcons from '@/components/Common/GlobalComps/orgIcons';
import { command } from '@/ts/base';
import { loadFileMenus, operatesToMenus } from '@/executor/fileOperate';
import { cleanMenus } from '@/utils/tools';
import { useFixedCallback } from '@/hooks/useFixedCallback';

const Panel = Collapse.Panel;

interface IProps {
  height?: string;
  openTask: (task: IAssignTask) => void;
}

const tags = ['单位任务', '个人任务'];

export default function TaskViewer(props: IProps) {
  const [space, setSpace] = useState<ICompany>();
  const [spaces, setSpaces] = useState<ICompany[]>([]);
  const [activeKey, setActiveKey] = useState('');

  const [tasks, setTasks] = useState<IAssignTask[]>([]);
  const [focusFile, setFocusFile] = useState<IAssignTask>();

  const [tag, setTag] = useState('单位任务');
  const [loading, setLoading] = useState(false);

  const refresh = useFixedCallback(async () => {
    if (space) {
      const tasks = await loadTasks(space, true);
      if (focusFile) {
        const newFile = tasks.find((t) => t.id == focusFile.id);
        if (newFile) {
          props.openTask(newFile);
          return;
        }
      }
      command.emitter('executor', 'close');
    }
  });

  useEffectOnce(() => {
    loadCompanys();
    const id = command.subscribe((type, flag, ...args: any[]) => {
      if (type == 'assign' && flag == 'refresh') {
        refresh();
      }
    });
    return () => {
      command.unsubscribe(id);
    };
  });

  useEffect(() => {
    if (space) {
      loadTasks(space);
    }
  }, [tag]);

  async function loadCompanys() {
    const companys = orgCtrl.user.companys;
    setSpaces(companys);
  }

  async function loadTasks(company: ICompany, reload = false) {
    setTasks([]);
    const tasks =
      tag == '单位任务'
        ? await company.loadAssignTasks(reload)
        : await company.loadPaddingTasks(reload);
    const uniqueTasks = tasks.sort((a, b) => {
      return (
        new Date(b.metadata.updateTime).getTime() -
        new Date(a.metadata.updateTime).getTime()
      );
    });
    console.warn(tasks);
    setTasks(uniqueTasks);
    return uniqueTasks;
  }
  async function fileOpen(entity: IAssignTask, dblclick: boolean) {
    if (dblclick) {
      return;
    } else {
      setFocusFile(entity);
      props.openTask(entity);
    }
  }

  async function cancelReceiveTask(entity: IAssignTask) {
    const ret = await entity.cancelReceive();
    if (!ret) {
      return;
    }
    message.success('取消接收任务成功');
    await loadTasks(space!);
  }

  const contextMenu = (file?: IFile) => {
    if (tag == '个人任务') {
      return {
        items: operatesToMenus(
          [
            {
              sort: 1,
              cmd: 'cancelReceive',
              label: '取消接收',
              iconType: 'restore',
            },
          ],
          file as IAssignTask,
        ),
        onClick: ({ key }: { key: string }) => {
          if (key === 'cancelReceive') {
            cancelReceiveTask(file as IAssignTask);
            command.emitter('assign', 'refresh');
          }
        },
      };
    }
    return {
      items: cleanMenus(loadFileMenus(file)) || [],
      onClick: ({ key }: { key: string }) => {
        command.emitter('executor', key, file);
      },
    };
  };

  return (
    <div className="task-viewer" style={{ height: props.height || '100%' }}>
      <div className="task-tags">
        {tags.map((t) => (
          <Tag className={tag == t ? 'is-active' : ''} key={t} onClick={() => setTag(t)}>
            {t}
          </Tag>
        ))}
        <div style={{ flex: 'auto' }}></div>
        <div className="chat-leftBar-search_more">
          <div className="chat-leftBar-search_more">
            <OrgIcons
              type="/operate/reload"
              size={22}
              notAvatar
              title="重载任务"
              onClick={async () => {
                try {
                  setLoading(true);
                  setActiveKey('');
                  await Promise.all(spaces.map((s) => loadTasks(s, true)));
                } finally {
                  setLoading(false);
                }
              }}
            />
          </div>
        </div>
        {tag == '单位任务' && (
          <div className="chat-leftBar-search_more">
            <div className="chat-leftBar-search_more">
              <OrgIcons
                type="/operate/newWork"
                size={22}
                notAvatar
                title="新建任务"
                onClick={() => command.emitter('executor', 'newReportTask', {})}
              />
            </div>
          </div>
        )}
      </div>
      <div className="directory-viewer group-collapse">
        {loading && <Spin spinning className="loading-spin" />}
        <Collapse
          accordion
          activeKey={activeKey}
          destroyInactivePanel
          onChange={(key) => {
            setActiveKey(key as string);
            if (key) {
              const unit = spaces.find((g) => g.id == key);
              if (unit) {
                setSpace(unit);
                loadTasks(unit);
              } else {
                console.warn(`不应该发生的情况：找不到组织群 ${key}`);
              }
            } else {
              setSpace(undefined);
              setTasks([]);
            }
          }}>
          {spaces.map((g) => {
            return (
              <Panel header={<EntityIcon entity={g.metadata} showName />} key={g.id}>
                {space?.id == g.id &&
                  (tasks.length > 0 ? (
                    <ListMode
                      selectFiles={[]}
                      focusFile={focusFile}
                      isMenu
                      content={tasks}
                      directory={g.directory}
                      fileOpen={(f, d) => fileOpen(f as IAssignTask, d)}
                      contextMenu={(f) => {
                        if (!f) {
                          return {};
                        } else {
                          return contextMenu(f as IAssignTask);
                        }
                      }}
                    />
                  ) : (
                    <Empty />
                  ))}
              </Panel>
            );
          })}
        </Collapse>
      </div>
    </div>
  );
}
